package org.rocky.provider.config;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.rocky.provider.exception.HostException;
import org.rocky.provider.exception.KeyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Rocky
 * @date 2020/2/16 21:30
 */
@Configuration
public class BindConfig {
    Logger log = LoggerFactory.getLogger(BindConfig.class);
//    @Bean("topicExchange")
//    public TopicExchange newTopicExchange(){
//        return new TopicExchange("TOPIC_EXCHANGE");
//    }
//
//    @Bean("directExchange")
//    public DirectExchange newDirectExchange(){
//        return new DirectExchange("DIRECT_EXCHANGE");
//    }
//
//    @Bean("fanoutExchange")
//    public FanoutExchange newFanoutExchange(){
//        return new FanoutExchange("FANOUT_EXCHANGE");
//    }
//
//    @Bean("directQueue")
//    public Queue newDirectConnQueue(){
//        return new Queue("DIRECT_QUEUE");
//    }
//
//    @Bean("preTopicQueue")
//    public Queue newPreTopicQueue(){
//        return new Queue("PRETOPIC_QUEUE");
//    }
//
//    @Bean("sufTopicQueue")
//    public Queue newSufTopicConn2Queue(){
//        return new Queue("SUFTOPIC_QUEUE");
//    }
//
//    @Bean("fanoutQueue")
//    public Queue newFanoutQueue(){
//        return new Queue("FANOUT_QUEUE");
//    }
//
//    /**
//     *  绑定键
//     *  直连  rocky.exchange
//     *  话题1 rocky.*
//     *  话题2 *.exchange
//     */
//    @Bean
//    public Binding bindDirect(@Qualifier("directQueue") Queue queue,@Qualifier("directExchange")  DirectExchange exchange){
//        return BindingBuilder.bind(queue).to(exchange).with("rocky.exchange");
//    }
//
//
//    @Bean
//    public Binding bindPreTopic(@Qualifier("preTopicQueue") Queue queue,@Qualifier("topicExchange")  TopicExchange exchange){
//        return BindingBuilder.bind(queue).to(exchange).with("rocky.*");
//    }
//
//    @Bean
//    public Binding bindSufTopic(@Qualifier("sufTopicQueue") Queue queue,@Qualifier("topicExchange")  TopicExchange exchange){
//        return BindingBuilder.bind(queue).to(exchange).with("*.exchange");
//    }
//
//    @Bean
//    public Binding bindFanout(@Qualifier(value = "fanoutQueue") Queue queue,@Qualifier("fanoutExchange")  FanoutExchange exchange){
//        return BindingBuilder.bind(queue).to(exchange);
//    }

    /**
     * 所有的消息发送都会转换成JSON格式发到交换机
     * @param connectionFactory 连接工厂
     * @return rabbit
     */
    @Bean
    public RabbitTemplate newMessageConverter(final ConnectionFactory connectionFactory) {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //消息转换--非message可以转换--message对象不行
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        //强制
        rabbitTemplate.setMandatory(true);

        /*
         * 事务处理--性能低下
         * rabbitTemplate.setChannelTransacted(true);
         */
         //confirm模式从provider发送到broker
         //异步处理，不会影响到发送服务，主要用来记录或者存储
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                if(!b){
                    log.info("消息发送失败:"+s);
                    throw new HostException("vhost绑定异常");
                }else {
                    log.info("消息成功被broker接收");
                }
            }
        });


        //路由-从交换机到queue
        //异常类型:绑定关系错误/队列不存在
        //异常出现时触发下面方法---可用来记录【日志】/【存储】---或者交由服务器转发到备份host
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                if (s1.equals("DELAY_EXCHANGE")){
                    return;
                }
                log.warn("key到queue异常");
                log.info("回发的消息:"+message.toString());
                log.info("replyCode:"+i);
                log.info("replyText:"+s);
                log.info("exchange:"+s1);
                log.info("routingKey:"+s2);
                throw new KeyException("key到queue异常");
            }
        });
        return rabbitTemplate;
    }




}
